#
# fusion.daemon
#
# Copyright 2006-2008 Helsinki Institute for Information Technology
# and the authors.
#
# Authors: Ken Rimey <rimey@hiit.fi>
#

# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from __future__ import with_statement

import time
import logging
from threading import Thread

from fusion.db.db import DB
from fusion.db.util import get_default_path

default_welcome = '3aa4a4ee109f3b364535f242a12f65c439607e6d'

def init_db(path):
    db = DB(path)
    try:
        with db.exclusive_transaction():
            if not db.get_local_info('welcome', None):
                db.subscribe(default_welcome)
                db.set_local_info('welcome', default_welcome)

            # XXX Temporary.  Add required rights to existing profiles.
            try:
                iid = db.get_my_iid()
                db.add_rights(iid, 'member-write', '/admin/secret/*/!')
            except LookupError:
                pass
    finally:
        db.close()

class FusionDaemon(object):
    def __init__(self, path=None,
                 sync=True, crawl=True, escrow=True, http=True,
                 sync_host='', sync_port=35800,
                 http_host='localhost', http_port=8080):
        self.path = path or get_default_path()

        self.sync = sync
        self.crawl = crawl
        self.escrow = escrow
        self.http = http

        self.sync_host = sync_host
        self.sync_port = sync_port

        self.http_host = http_host
        self.http_port = http_port

    def loop(self):
        self.init()
        self.start()
        wait_for_keyboard_interrupt()
        self.stop()
        print 'Exiting...'

    def init(self):
        init_db(self.path)

    def start(self):
        if self.sync:
            self.start_sync()

        if self.crawl:
            self.start_crawl()

        if self.escrow:
            self.start_escrow()

        if self.http:
            self.start_http()

    def stop(self):
        if self.sync:
            self.daemon.close()
            self.sync_thread.join()

    def start_sync(self):
        from fusion.sync.sync_daemon import SyncDaemon

        self.daemon = SyncDaemon(path=self.path,
                                 host=self.sync_host,
                                 port=self.sync_port)
        self.sync_thread = Thread(target=self.daemon.loop,
                                  name='sync-thread')
        self.sync_thread.start()

    def start_crawl(self):
        from fusion.sync.crawl import Crawler

        self.crawler = Crawler(path=self.path)
        self.crawler_thread = Thread(target=self.crawler.loop,
                                     name='crawler-thread')
        self.crawler_thread.setDaemon(True)
        self.crawler_thread.start()

    def start_escrow(self):
        from fusion.db.escrow import EscrowAgent

        self.escrow_agent = EscrowAgent(path=self.path)
        self.escrow_thread = Thread(target=self.escrow_agent.loop,
                                    name='escrow-thread')
        self.escrow_thread.setDaemon(True)
        self.escrow_thread.start()

    def start_http(self):
        from fusion.http.wsgiserver import serve

        args = self.path, self.http_host, self.http_port
        self.http_thread = Thread(target=serve, args=args,
                                  name='http-thread')
        self.http_thread.setDaemon(True)
        self.http_thread.start()

def wait_for_keyboard_interrupt():
    try:
        while True:
            time.sleep(30)
    except KeyboardInterrupt:
        pass

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    daemon = FusionDaemon()
    daemon.loop()
